//给定一个只包括 '('，')'，'{'，'}'，'['，']' 的字符串 s ，判断字符串是否有效。
//
// 有效字符串需满足：
//
//
// 左括号必须用相同类型的右括号闭合。
// 左括号必须以正确的顺序闭合。
//
//
//
//
// 示例 1：
//
//
//输入：s = "()"
//输出：true
//
//
// 示例 2：
//
//
//输入：s = "()[]{}"
//输出：true
//
//
// 示例 3：
//
//
//输入：s = "(]"
//输出：false
//
//
// 示例 4：
//
//
//输入：s = "([)]"
//输出：false
//
//
// 示例 5：
//
//
//输入：s = "{[]}"
//输出：true
//
//
//
// 提示：
//
//
// 1 <= s.length <= 10⁴
// s 仅由括号 '()[]{}' 组成
//
// Related Topics 栈 字符串 👍 2936 👎 0

package leetcode.editor.cn;

import java.util.ArrayDeque;
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("all")
//Java：有效的括号
public class 有效的括号 {
    public static void main(String[] args) {
        Solution solution = new 有效的括号().new Solution();
        // TO TEST
    }

    //leetcode submit region begin(Prohibit modification and deletion)
    class Solution {
        private Map<Character, Character> close = new HashMap<Character, Character>() {
            {
                put(')', '(');
                put(']', '[');
                put('}', '{');

            }
        };

        public boolean isValid(String s) {
            if (s == null || s.length() % 2 == 1)
                return false;
            ArrayDeque<Character> open = new ArrayDeque<>();

            for (int i = 0; i < s.length(); i++) {
                char ch = s.charAt(i);
                if (close.containsKey(ch)) {//说明当前是一个关括号
                    if (open.isEmpty() || open.peekFirst() != close.get(ch)) {
                        //栈内无开括号与之对应
                        return false;
                    }
                    open.pop();
                } else {//说明是一个开括号，压入栈中
                    open.push(ch);
                }
                if (s.length() - i - 1 < open.size())//假设后面元素都是关括号，当后关括号总和小于当前未抵消的开括号
                    return false;
            }
            return open.isEmpty();
        }
    }
//leetcode submit region end(Prohibit modification and deletion)


}
